package com.sky.service.rider.Impl;

import cn.hutool.core.date.DateException;
import com.sky.constant.MessageConstant;
import com.sky.dto.CourierTradeQueryDto;
import com.sky.mapper.rider.CourierMapper;
import com.sky.mapper.rider.ShotUriMapper;
import com.sky.mapper.rider.CourierTradeOrderMapper;
import com.sky.mapper.user.OrderDetailMapper;
import com.sky.mapper.user.OrdersMapper;
import com.sky.pojo.*;
import com.sky.properties.ShortUriProperties;
import com.sky.result.Result;
import com.sky.service.rider.CourierService;
import com.sky.utils.MapUtils;
import com.sky.utils.ShortUriGenerator;
import com.sky.vo.CourierTradeOrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CourierServiceImpl implements CourierService {
    @Autowired
    private CourierMapper courierMapper;
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private ShortUriGenerator shortUriGenerator;
    @Autowired
    private ShortUriProperties shortUriProperties;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ShotUriMapper shotUriMapper;
    @Autowired
    private CourierTradeOrderMapper courierTradeOrderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Override
    public Courier selectByPhone(String telephone) {
        return courierMapper.selectByPhone(telephone);
    }

    @Override
    public List<CourierTradeOrderVO> queryPendingOrders(CourierTradeQueryDto dto) {
        if (null==dto || null==dto.getCourierId()){
            throw new DateException(MessageConstant.DATA_ERROR);
        }
       List<CourierTradeOrder> courierTradeOrderList= courierMapper.selectByList(dto);

        Courier courier = courierMapper.selectById(dto.getCourierId());
        String curLocation = courier.getCurLocation();
        List<CourierTradeOrderVO> courierTradeOrderVO = new ArrayList<>();
        for (CourierTradeOrder courierTradeOrder : courierTradeOrderList) {
            CourierTradeOrderVO vo = new CourierTradeOrderVO();
            BeanUtils.copyProperties(courierTradeOrder,vo);
            //商家坐标
            String addressToLnglat = MapUtils.addressToLnglat(courierTradeOrder.getShopAddress());
            //商家到骑手距离
            double ShopAndCourierDistance = MapUtils.calculateDistance(addressToLnglat, curLocation);
            vo.setShopAndCourierDistance(ShopAndCourierDistance);
            //用户坐标
            String addressToLnglat1 = MapUtils.addressToLnglat(courierTradeOrder.getCustomerAddress());
            //商家到用户距离
            double calculateDistance = MapUtils.calculateDistance(curLocation, addressToLnglat1);
            vo.setShopAndCustomerDistance(calculateDistance);
            //预计送达时间
            long time = Duration.between(LocalDateTime.now(), courierTradeOrder.getCustomerExpectedDeliveryTime()).get(ChronoUnit.SECONDS);
            vo.setCurrentTimeAndCustomerExpectedTime(time);
            courierTradeOrderVO.add(vo);
        }

        AtomicInteger sort = new AtomicInteger(1);
        courierTradeOrderVO = courierTradeOrderVO.stream().sorted(Comparator.comparing(CourierTradeOrderVO::getShopAndCourierDistance)).map(vo -> {
            vo.setMarkSort(sort.getAndIncrement());
            return vo;
        }).collect(Collectors.toList());

        return courierTradeOrderVO;
    }

    @Override
    public CourierTradeOrder selectByNum(String tradeNo) {
       return courierMapper.selectTradeOrderById(tradeNo);

    }

    @Override
    public Result<String> receivingOrder(Long courierId, String tradeNo) {
        if (null==courierId||null==tradeNo){
            throw new DateException(MessageConstant.DATA_ERROR);
        }
        //查运单
        CourierTradeOrder courierTradeOrder = courierMapper.selectTradeOrderByTradeNo(tradeNo);
        if (null==courierTradeOrder){
            throw new DateException(MessageConstant.DATA_ERROR);
        }
        //改状态
        courierTradeOrder.setWaybillStatus(CourierTradeOrder.DELIVORING);
        courierTradeOrderMapper.updetById(courierTradeOrder);
        //查订单,改状态
        Orders orders = new Orders();
        orders.setNumber(courierTradeOrder.getOrderNumber());
        orders.setStatus(Orders.TOBEPICKEDUP);
        ordersMapper.update(orders);

        //生成随机字符串
        String ren ="";
        while (true){
            ren = shortUriGenerator.creatKey();
            Long index =0L;
            int hashCode  = ren.hashCode();
            if (hashCode<0){
                index= Math.abs(hashCode)+2147483648l;
            }else {
                index= (long) hashCode;
            }
            Boolean flas = redisTemplate.opsForValue().getBit("short_code", index);
            if (!flas){
                redisTemplate.opsForValue().setBit("short_code", index,true);
                break;
            }
        }

        StringBuilder codeSb = new StringBuilder();
        //短链接
        String code = codeSb
                .append(shortUriProperties.getDomainName())
                .append(shortUriProperties.getShortUrlPrefix())
                .append(shortUriProperties.getRealResource())
                .append(ren).toString();
        //完整链接
        StringBuilder urlSb = new StringBuilder();
        String full = urlSb.append(shortUriProperties.getDomainName())
                .append(shortUriProperties.getShortUrlPrefix())
                .append(shortUriProperties.getRealResource())
                .append("tradeNo=")
                .append(tradeNo)
                .append("&")
                .append("courierId=")
                .append("&")
                .append("expire=null")
                .toString();
        //将长短链接存入数据库
        ShotUri shotUri = ShotUri.builder()
                .shotUrl(code)
                .fullUrl(full)
                .shortCode(ren)
                .expireTime(LocalDateTime.now())
                .tradeNo(tradeNo)
                .build();
        shotUriMapper.insert(shotUri);
        //给骑手发短信
        System.out.println(code);
        return Result.success();
    }

    @Override
    public List<OrderDetail> confirmPickUpList(String tradeNo) {
        if (null==tradeNo){
            throw new DateException(MessageConstant.DATA_ERROR);
        }
      CourierTradeOrder courierTradeOrder =courierTradeOrderMapper.selectTradeOrderBytradeNo(tradeNo);
        if (null==courierTradeOrder){
            throw new DateException(MessageConstant.DATA_ERROR);
        }
        Orders orders = ordersMapper.selectByNumber(courierTradeOrder.getOrderNumber());
        List<OrderDetail>orderDetailslist= orderDetailMapper.selectByOrderId(orders.getId());

        return orderDetailslist;
    }

    @Override
    public Courier findById(Long id) {
        return courierMapper.selectById(id);
    }
}
